package com.ruoyi.project.mgr.arrange.controller;

import java.util.*;
import java.util.stream.Collectors;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.project.mgr.arrange.vo.MonthDayVO;
import com.ruoyi.project.mgr.arrange.vo.WeekDayVO;
import com.ruoyi.project.mgr.clazz.domain.MgrClazz;
import com.ruoyi.project.mgr.clazz.service.IMgrClazzService;
import com.ruoyi.project.mgr.course.domain.MgrCourse;
import com.ruoyi.project.mgr.course.service.IMgrCourseService;
import com.ruoyi.project.mgr.room.domain.MgrRoom;
import com.ruoyi.project.mgr.room.service.IMgrRoomService;
import com.ruoyi.project.mgr.teacher.domain.MgrTeacher;
import com.ruoyi.project.system.dict.domain.DictData;
import com.ruoyi.project.system.dict.service.IDictDataService;
import com.ruoyi.project.system.role.domain.Role;
import com.ruoyi.project.system.role.service.IRoleService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.framework.aspectj.lang.annotation.Log;
import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
import com.ruoyi.project.mgr.arrange.domain.MgrCourseArrange;
import com.ruoyi.project.mgr.arrange.service.IMgrCourseArrangeService;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.page.TableDataInfo;

/**
 * 课程安排Controller
 * 
 * @author .
 * @date 2020-02-11
 */
@Controller
@RequestMapping("/mgr/arrange")
public class MgrCourseArrangeController extends BaseController
{
    private String prefix = "mgr/arrange";

    @Autowired
    private IMgrCourseArrangeService mgrCourseArrangeService;

    @Autowired
    private IMgrCourseService mgrCourseService;

    @Autowired
    private IMgrRoomService mgrRoomService;

    @Autowired
    private IMgrClazzService mgrClazzService;

    @Autowired
    private IDictDataService dictDataService;

    @Autowired
    private IRoleService roleService;

    @GetMapping()
    public String clazz(Long clazzId, String day, ModelMap modelMap)
    {
        modelMap.put("clazzId", clazzId);
        modelMap.put("day", day);
        return prefix + "/arrange";
    }

    /**
     * 查询课程安排列表
     */
    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo list(MgrCourseArrange mgrCourseArrange)
    {
        startPage();
        List<MgrCourseArrange> list = mgrCourseArrangeService.selectMgrCourseArrangeList(mgrCourseArrange);
        return getDataTable(list);
    }

    /**
     * 导出课程安排列表
     */
    @Log(title = "课程安排", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    @ResponseBody
    public AjaxResult export(MgrCourseArrange mgrCourseArrange)
    {
        List<MgrCourseArrange> list = mgrCourseArrangeService.selectMgrCourseArrangeList(mgrCourseArrange);
        ExcelUtil<MgrCourseArrange> util = new ExcelUtil<MgrCourseArrange>(MgrCourseArrange.class);
        return util.exportExcel(list, "arrange");
    }

    /**
     * 新增课程安排
     */
    @GetMapping("/add")
    public String add(Long clazzId, String day, ModelMap modelMap)
    {
        modelMap.put("clazzId", clazzId);
        modelMap.put("day", day);
        modelMap.put("courses", mgrCourseService.selectCourseByTeacher(clazzId));
        MgrRoom mgrRoom = new MgrRoom();
        mgrRoom.setStatus(0);
        modelMap.put("rooms", mgrRoomService.selectMgrRoomList(mgrRoom));
        return prefix + "/add";
    }

    /**
     * 新增保存课程安排
     */
    @Log(title = "课程安排", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    @ResponseBody
    public AjaxResult addSave(MgrCourseArrange mgrCourseArrange)
    {
        AjaxResult result = addCheck(mgrCourseArrange);
        if ("500".equals(result.get(AjaxResult.CODE_TAG).toString())) {
            return result;
        }
        return toAjax(mgrCourseArrangeService.insertMgrCourseArrange(mgrCourseArrange));
    }

    /**
     * 新增时校验
     * @param mgrCourseArrange
     * @return
     */
    public AjaxResult addCheck(MgrCourseArrange mgrCourseArrange) {
        if (mgrCourseArrange.getCourseSize() == 0) {
            return error("请选择一门课程！");
        } else if (mgrCourseArrange.getCourseSize() > 1) {
            return error("一节课只能选择一门课程！");
        }
        MgrCourse mgrCourse = mgrCourseService.selectByCourseName(mgrCourseArrange.getCourseName());
        if (mgrCourse == null) {
            return error("一节课只能选择一门课程！");
        }
        mgrCourseArrange.setTeacherId(mgrCourse.getTeacherId());
        mgrCourseArrange.setCourseId(mgrCourse.getCourseId());

        // 该班级当前时间段是否已排课
        MgrCourseArrange courseClazz = new MgrCourseArrange();
        courseClazz.setTimeSlot(mgrCourseArrange.getTimeSlot());
        courseClazz.setClazzId(mgrCourseArrange.getClazzId());
        courseClazz.setDay(mgrCourseArrange.getDay());
        List<MgrCourseArrange> arrangeList = mgrCourseArrangeService.selectMgrCourseArrangeList(courseClazz);
        if (arrangeList != null && arrangeList.size() > 0) {
            return error("当前时间已排过课！");
        }

        MgrCourseArrange courseRoom = new MgrCourseArrange();
        courseRoom.setTimeSlot(mgrCourseArrange.getTimeSlot());
        courseRoom.setRoomId(mgrCourseArrange.getRoomId());
        courseRoom.setDay(mgrCourseArrange.getDay());
        // 根据选择的时间段和教室查询是否当前时间教室被占用
        List<MgrCourseArrange> courseRoomList = mgrCourseArrangeService.selectMgrCourseArrangeList(courseRoom);
        if (courseRoomList != null && courseRoomList.size() > 0) {
            return error("该教室当前时间段已被占用！");
        }
        MgrCourseArrange courseTeacher = new MgrCourseArrange();
        courseTeacher.setTimeSlot(mgrCourseArrange.getTimeSlot());
        courseTeacher.setTeacherId(mgrCourseArrange.getTeacherId());
        courseTeacher.setDay(mgrCourseArrange.getDay());
        // 根据选择的时间段和教室查询是否当前时间教室被占用
        List<MgrCourseArrange> courseTeacherList = mgrCourseArrangeService.selectMgrCourseArrangeList(courseRoom);
        if (courseTeacherList != null && courseTeacherList.size() > 0) {
            return error("该教师当前时间段已排课！");
        }
        return success();
    }
    /**
     * 修改课程安排
     */
    @GetMapping("/edit/{id}")
    public String edit(@PathVariable("id") Long id, ModelMap mmap)
    {
        MgrCourseArrange courseArrange = mgrCourseArrangeService.selectMgrCourseArrangeById(id);
        List<MgrCourse> courseList = mgrCourseService.selectCourseByTeacher(courseArrange.getClazzId());
        courseList.stream().forEach(s -> {
            if (s.getCourseId().equals(courseArrange.getCourseId())) {
                s.setFlag(true);
            }
        });
        mmap.put("courses", courseList);
        MgrRoom mgrRoom = new MgrRoom();
        mgrRoom.setStatus(0);
        List<MgrRoom> roomList = mgrRoomService.selectMgrRoomList(mgrRoom);
        roomList.stream().forEach(s -> {
            if (s.getRoomId().equals(courseArrange.getRoomId())) {
                s.setFlag(true);
            }
        });
        mmap.put("rooms", roomList);
        MgrCourseArrange mgrCourseArrange = mgrCourseArrangeService.selectMgrCourseArrangeById(id);
        mmap.put("mgrCourseArrange", mgrCourseArrange);
        return prefix + "/edit";
    }

    /**
     * 修改保存课程安排
     */
    @Log(title = "课程安排", businessType = BusinessType.UPDATE)
    @PostMapping("/edit")
    @ResponseBody
    public AjaxResult editSave(MgrCourseArrange mgrCourseArrange)
    {
        AjaxResult result = editCheck(mgrCourseArrange);
        if ("500".equals(result.get(AjaxResult.CODE_TAG).toString())) {
            return result;
        }
        MgrCourse course = mgrCourseService.selectMgrCourseById(mgrCourseArrange.getCourseId());
        mgrCourseArrange.setTeacherId(course.getTeacherId());
        return toAjax(mgrCourseArrangeService.updateMgrCourseArrange(mgrCourseArrange));
    }

    public AjaxResult editCheck(MgrCourseArrange mgrCourseArrange) {

        MgrCourseArrange arrange = mgrCourseArrangeService.selectMgrCourseArrangeById(mgrCourseArrange.getId());
        // 班级id
        Long clazzId = arrange.getClazzId();
        // 日期
        String day = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, arrange.getCourseDate());
        boolean flag = false;

        // 根据班级id 时间 时间段
        MgrCourseArrange courseArrange = new MgrCourseArrange();
        courseArrange.setClazzId(clazzId);
        courseArrange.setDay(day);
        courseArrange.setTimeSlot(mgrCourseArrange.getTimeSlot());
        // 查询是否存在记录 如果有 只会查出一条记录 新增时已做过限制
        List<MgrCourseArrange> courseArrangeList = mgrCourseArrangeService.selectMgrCourseArrangeList(courseArrange);
        if (courseArrangeList != null && courseArrangeList.size() > 0) {
            // 如果存在记录并且不是当前修改的数据
            flag = courseArrangeList.stream().allMatch(s -> !s.getId().equals(mgrCourseArrange.getId()));
            if (flag) {
                return error("本班级当前时间已排过课！");
            }
        }

        MgrCourseArrange courseRoom = new MgrCourseArrange();
        courseRoom.setTimeSlot(mgrCourseArrange.getTimeSlot());
        courseRoom.setRoomId(mgrCourseArrange.getRoomId());
        courseRoom.setDay(mgrCourseArrange.getDay());
        // 根据选择的时间段和教室查询是否当前时间教室被占用
        List<MgrCourseArrange> courseRoomList = mgrCourseArrangeService.selectMgrCourseArrangeList(courseRoom);
        if (courseRoomList != null && courseRoomList.size() > 0) {
            flag = courseRoomList.stream().allMatch(s -> !s.getId().equals(mgrCourseArrange.getId()));
            if (flag) {
                return error("该教室当前时间段已被占用！");
            }

        }
        MgrCourseArrange course = new MgrCourseArrange();
        course.setTimeSlot(mgrCourseArrange.getTimeSlot());
        course.setCourseId(mgrCourseArrange.getCourseId());
        course.setDay(mgrCourseArrange.getDay());
        // 根据选择的时间段和教室查询是否当前时间教室被占用
        List<MgrCourseArrange> courseList = mgrCourseArrangeService.selectMgrCourseArrangeList(courseRoom);

        if (courseList != null && courseList.size() > 0) {
            // 因为只可能有一条数据
            MgrCourseArrange mgrCourse = courseList.get(0);
            if (!mgrCourse.getId().equals(mgrCourseArrange.getId())) {
                MgrClazz clazz = mgrClazzService.selectMgrClazzById(mgrCourse.getClazzId());
                return error(clazz.getClazzName() +"当前时间段已排该课程！");
            }
        }
        return success();
    }
    /**
     * 删除课程安排
     */
    @Log(title = "课程安排", businessType = BusinessType.DELETE)
    @PostMapping( "/remove")
    @ResponseBody
    public AjaxResult remove(String ids)
    {
        return toAjax(mgrCourseArrangeService.deleteMgrCourseArrangeByIds(ids));
    }

    @GetMapping("/arrange/{clazzId}")
    public String arrange(@PathVariable("clazzId")Long clazzId, ModelMap modelMap)
    {
        // 当前月的所有天
        List<String> monthDayList = DateUtils.getAllTheDateOftheMonth(new Date());
        List<MonthDayVO> monthDayVOList = mgrCourseArrangeService.selectDays(monthDayList);

        List<List> mapList = new ArrayList<>();
        for (String day : monthDayList) {
            List<String> list = new ArrayList<>();
            list.add(day);
            Optional<MonthDayVO> optional = monthDayVOList.stream().filter(s -> s.getDay().equals(day)).findFirst();
            if (optional.isPresent()) {
                list.add("已排课");
                list.add(optional.get().getNum().toString() + "节");
            } else {
                list.add("未排课");
            }
            mapList.add(list);
        }
        String data = JSON.toJSONString(mapList);
        mapList = null;
        modelMap.put("month", DateUtils.parseDateToStr(DateUtils.YYYY_MM, new Date()));
        modelMap.put("clazzId", clazzId);
        modelMap.put("data", data);
        return prefix + "/course_arrange";
    }

    @GetMapping("/searchMonthDays")
    @ResponseBody
    public AjaxResult searchMonthDays(String month)
    {
        Date firstDay = DateUtils.parseDate(month + "-01");

        // 当前月的所有天
        List<String> monthDayList = DateUtils.getAllTheDateOftheMonth(firstDay);
        List<MonthDayVO> monthDayVOList = mgrCourseArrangeService.selectDays(monthDayList);

        List<List> mapList = new ArrayList<>();
        for (String day : monthDayList) {
            List<String> list = new ArrayList<>();
            list.add(day);
            Optional<MonthDayVO> optional = monthDayVOList.stream().filter(s -> s.getDay().equals(day)).findFirst();
            if (optional.isPresent()) {
                list.add("已排课");
                list.add(optional.get().getNum().toString() + "节");
            } else {
                list.add("未排课");
            }
            mapList.add(list);
        }
        String data = JSON.toJSONString(mapList);
        mapList = null;
        return AjaxResult.success("操作成功", data);
    }



    @GetMapping("/myCourse")
    public String myCourse(ModelMap modelMap) {
        String data = null;
        List<Role> roleList = roleService.selectRolesByUserId(ShiroUtils.getUserId()).stream().filter(s-> s.isFlag()).collect(Collectors.toList());
        Role role = roleList.get(0);
        List<String> dateList = DateUtils.dateToWeek(new Date(), 5);
        if (ShiroUtils.getSysUser().isAdmin() || "educational".equals(role.getRoleKey())) {
            List<MgrClazz> clazzList = mgrClazzService.selectMgrClazzList(new MgrClazz());
            modelMap.put("clazzs", clazzList);
            data = getData(dateList, clazzList.get(0).getClazzId());
            modelMap.put("view", true);
        }

        if ("teacher".equals(role.getRoleKey())) {
            List<MgrClazz> clazzList = mgrClazzService.selectClazzByTeacher(ShiroUtils.getUserId());
            if (clazzList.size() > 0) {
                data = getData(dateList, clazzList.get(0).getClazzId());
            }

            modelMap.put("clazzs", clazzList);
            modelMap.put("view", true);
        } else if("student".equals(role.getRoleKey())) {
            MgrClazz mgrClazz = new MgrClazz();
            mgrClazz.setClazzId(ShiroUtils.getSysUser().getClazzId());
            modelMap.put("clazzs", mgrClazzService.selectMgrClazzList(mgrClazz));
            data = getData(dateList, ShiroUtils.getSysUser().getClazzId());
            modelMap.put("view", false);
        }
        // 时间周期
        modelMap.put("cycle", dateList.get(0) + " ~ " + dateList.get(4));
        modelMap.put("data", data);
        modelMap.put("day", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, new Date()));
        modelMap.put("dictLabel", getDictLabel());
        return prefix + "/my_course";
    }

    @GetMapping("/searchDays")
    @ResponseBody
    public AjaxResult searchDays(String day, Long clazzId, int num) {
        Date date = null;
        if (num == 0) {
            date = new Date();
        } else {
            date = DateUtils.addWeeks(DateUtils.parseDate(day), num);
        }
        List<String> dateList = DateUtils.dateToWeek(date, 5);
        // 课程表数据
        String data = getData(dateList, clazzId);
        // 字典数据
        String dictLabel = getDictLabel();
        Map<String, String> map = new HashMap<>();
        map.put("data", data);
        map.put("dictLabel", dictLabel);
        map.put("day", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, date));
        map.put("cycle", dateList.get(0) + " ~ " + dateList.get(4));
        return AjaxResult.success(map);
    }


    /**
     * 根据时间班级获取数据
     * @param dateList
     * @param clazzId
     * @return
     */
    public String getData(List<String> dateList, Long clazzId) {
        WeekDayVO weekDayVO = new WeekDayVO();
        weekDayVO.setClazzId(clazzId);
        weekDayVO.setStartDay(dateList.get(0));
        weekDayVO.setEndDay(dateList.get(4));
        List<WeekDayVO> weekDayVOList = mgrCourseArrangeService.selectMyArrange(weekDayVO);
        List<List> dataList = new ArrayList<>();
        for (String day : dateList) {
            List<WeekDayVO> dayList = weekDayVOList.stream().filter(s -> day.equals(s.getDay())).collect(Collectors.toList());
            if (dayList.size() > 0) {
                for (WeekDayVO dayVO : dayList) {
                    List<Object> list = new ArrayList<>();
                    list.add(dayVO.getCourseName());
                    list.add(dayVO.getWeekDay());
                    list.add(dayVO.getTimeSlot());
                    list.add(1);
                    dataList.add(list);
                }
            }
        }
        String data = JSON.toJSONString(dataList);
        dataList = null;
        return data;
    }

    /**
     *  查询时间段的字典数据
     * @return
     */
    public String getDictLabel() {

        List<DictData> dictDataList = dictDataService.selectDictDataByType("course_time_slot");
        List<String> dictLabelList = dictDataList.stream().map(s -> s.getDictLabel()).collect(Collectors.toList());

        return JSON.toJSONString(dictLabelList);
    }

}
